import java.util.ArrayList;
import java.util.HashMap;

public class Vertex
{
	
	private String name;
	private boolean mark;
	private int weight;
	private ArrayList<HashMap<String, Vertex>> adjacentVertex;
    private ArrayList<HashMap<Vertex, Integer>> adjacentVertexWeight;
	
	public Vertex()
	{
		this("");
		
	}
	
	public Vertex(String name)
	{
		this.weight = 0;
		this.name = name;
		adjacentVertex = new ArrayList<HashMap<String, Vertex>>();
		adjacentVertexWeight = new ArrayList<HashMap<Vertex, Integer>>();
	    mark = false;	
	}
	
	/**
	 * Add adjacent vertex to it
	 * @param adj
	 * @return
	 */
	public boolean addAdjacentVertex(Vertex adj)
	{
//		System.out.println("addAdjacentVertex runs");

		// make a new vertex adj to vertex's adjacentVertex
		HashMap<String, Vertex> temp = new HashMap<String, Vertex>();
		temp.put(adj.getName(), adj);
		
		/* ignore it if it already exists 
		 * add it otherwise
		 */
		if(adj == null || adjacentVertex.contains(temp))
		{
			System.out.println("Opps adding failed, "+ adj.getName() +" already exists");
			return false;
		}
		else
		{
			adjacentVertex.add(temp);
			return true;
		}
	}
	
	/**
	 * Add its corresponding weight to its adjacent vertex
	 * @param adj
	 * @param weight
	 * @return
	 */
	public boolean addAdjacentWeight(Vertex adj, int weight)
	{
//		System.out.println("addAdjacentWeight runs before addVertex");

	    if(addAdjacentVertex(adj))
	    {
//	    	System.out.println("addAdjacentWeight runs after addVertex");

			// add to vertex's weight to corresponding adjacent Vertex
			HashMap<Vertex, Integer> temp = new HashMap<Vertex, Integer>();
			temp.put(adj, weight);
			adjacentVertexWeight.add(temp);
			return true;
	    }
	    else
	    	return false;
	    	
	}

	/**
	 * Add vertex and its corresponding weight
	 * @param v
	 * @param weight
	 * @return
	 */
	public boolean addAdjacent(Vertex v, int weight)
	{
//		System.out.println("addAdjacent runs");
		System.out.println("Attempting to add -> " +v.getName()
				           +" has been added with weight "+ weight);
		return addAdjacentWeight(v, weight);

	}
	
	/**
	 * Overriding the toString method
	 */
	public String toString()
	{
//	   System.out.println("toString works");
	   System.out.println("AdjacentVertex size is "+ adjacentVertex.size());
		

	   String temp = "Empty";
       if(adjacentVertex.isEmpty() == false)
       {
	    	temp = " "; // reset temp string
			for(int i = 0; i< adjacentVertex.size(); i++)
			{
				
	//			temp = "<" + adjacentVertex.get(i).get(name) +", " 
	//		           + adjacentVertexWeight.get(i).get(name)  + ">";
				
				temp += "<" + adjacentVertex.get(i).values().toString() +", " 
				           + adjacentVertexWeight.get(i).values().toString()  + ">";
			}
	       }
		
		return temp;
	}

	
	/********************************************************
	 *                Setters and getters                   *
	 ********************************************************/
    
	/**
     * getter for name
     * @return
     */
	public String getName()
	{
		return name;
	}

	/**
	 * setter for name
	 * @param name
	 */
	public void setName(String name)
	{
		this.name = name;
	}

	/**
	 * See if the vertex is visited or not
	 * @return
	 */
	public boolean isVisited()
	{
		return mark;
	}	

	 /**
	  * Set the mark visited or not
	  * @param mark
	  */
	public void setMark(boolean mark)
	{
		this.mark = mark;
	}
	
	public ArrayList<HashMap<String, Vertex>> getAdjacentVertex()
	{
		return adjacentVertex;
	}
	public void setAdjacentVertex(ArrayList<HashMap<String, Vertex>> adjacentVertex)
	{
		this.adjacentVertex = adjacentVertex;
	}
	public ArrayList<HashMap<Vertex, Integer>> getAdjacentVertexWeight()
	{
		return adjacentVertexWeight;
	}
	public void setAdjacentVertexWeight(
	        ArrayList<HashMap<Vertex, Integer>> adjacentVertexWeight)
	{
		this.adjacentVertexWeight = adjacentVertexWeight;
	}
	

}
